package com.teamwings.config.filter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;

public class AutoFormFilter implements Filter {
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;

		String contentType = httpRequest.getContentType();
		// 文件上传先跳过过滤
		if (StringUtils.isNotEmpty(contentType) && contentType.startsWith("multipart/")) {
			// todo 遇到文件先放行， 文件上传的过滤器后面再考虑
			chain.doFilter(request, response);
			return;
		}


        String uri = httpRequest.getRequestURI();
        if (uri.startsWith("/form//")) {
            uri = uri.replace("form//", "form/");
        }

		// 路径过滤白名单 （有某些请求会被 判断为不符合安全规则） 所以跳过过滤
        /**
         *   '/form/code/import' 表单导入
         */
        if(uri.equals("/form/code/import")){
            chain.doFilter(request, response);
            return;
        }

		ParameterRequestWrapper wrapper = new ParameterRequestWrapper(httpRequest);
		if (wrapper.checkParameter()) {
			/*
			 * 表单设计编辑，添加的代码有可能被判断为不符合安全规则
			 *
			 * wrapper.checkParameter()调用的checkXssAndSql方法，这个方法会判断前端是否传递一些sql语句到后台，
			 * 比如update, delete等，如果你前台表单设计内，存在这些关键词，就会被过滤掉。
			 */

			// todo 需要跳过sql注入校验的接口
			if (uri.endsWith("design/edit") || uri.endsWith("design/add")
					|| uri.equals("/form/ctrl/logic_table") || uri.endsWith("design/saveWithTemplate")) {
				chain.doFilter(wrapper, response);
				return;
			}

			response.setCharacterEncoding("UTF-8");
			PrintWriter out = response.getWriter();
			out.write("违反安全规则");
			return;
		}
		chain.doFilter(wrapper, response);

		/*String method = httpRequest.getMethod();
		AutoFormWrapper xssRequest = new AutoFormWrapper(httpRequest);
		if (methodType[0].equalsIgnoreCase(method)) {
			if (xssRequest.checkParameter()) {
				response.setCharacterEncoding("UTF-8");
				PrintWriter out = response.getWriter();
				out.write("违反安全规则");
				return;
			}
		}
		if (methodType[1].equalsIgnoreCase(method) || methodType[2].equalsIgnoreCase(method)) {
			String param = getBodyString(xssRequest.getReader());
			// 2021-08-27 有些请求不是json结构
			param = param.replaceAll("^[\n ]+", "").trim();
			if (param.startsWith("{") || param.startsWith("[")) {
				Map result = JSON.parseObject(param, Map.class);
				if (result != null) {
					// 遍历value值
					for (Object value : result.values()) {
						if (value != null) {
							if (xssRequest.checkXssAndSql(value.toString())) {
								response.setCharacterEncoding("UTF-8");
								response.setContentType("text/html;charset=utf-8");
								PrintWriter out = response.getWriter();
								out.write("违反安全规则: " + value.toString());
								return;
							}
						}
					}
				}
			}
		}
		chain.doFilter(xssRequest, response);*/
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
	}

	/**
	 * 获取request请求body中参数
	 * @param br BufferedReader
	 * @return /
	 */
	public static String getBodyString(BufferedReader br) {
		String inputLine;
		StringBuilder str = new StringBuilder();
		try {
			while ((inputLine = br.readLine()) != null) {
				str.append(inputLine);
			}
			br.close();
		} catch (IOException e) {
			System.out.println("IOException: " + e);
		}
		return str.toString();
	}

}
